﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.VisualBasic;
using System.IO;

namespace read
{
    public partial class Form1 : Form
    {
        private string fileName = "";
        private Point mouseOffset;
        private bool isMouseDown;
        private bool isShow = true;
        //private int index = 0;
        private int startIndex = 0;
        private string strTxt = "";
        private int step = 40;
        private int len;
        private float fontsize = 13f;
        public Form1()
        {
            InitializeComponent();
            InitLblCms();
            this.Width = 900;
            this.Height = 30;
            lbl.Font = new Font("宋体", fontsize);
            this.MouseWheel += new MouseEventHandler(Form1_MouseWheel);
            lbl.BorderStyle = BorderStyle.FixedSingle;
        }

        string msg = "O:打开文件\n"
                      + "A:重新载入\n"
                      + "F:搜索文本并定位\n"
                      + "L:定位到索引处\n"
                      + "P:定位到百分比处\n"
                      + "R:每次显示的字数\n"
                      + "W:向上翻页\n"
                      + "Up:向上翻页\n"
                      + "S:向下翻页\n"
                      + "Down:向下翻页\n"
                      + "B:调整背景色\n"
                      + "U:以UTF8编码读取文件\n"
                      + "C:调整字体颜色\n"
                      + "K:调整字符大小\n"
                      + "F5:减小长度\n"
                      + "F6:增加长度\n"
                      + "F7:减小高度\n"
                      + "F8:增加高度\n"
                      + "F11:查看当前进度\n"
                      + "F12:复制当前内容\n"
                      + "Escape:隐藏窗体\n"
                      + "Q:退出";
        private void InitLblCms()
        {


            string[] keyInfo = msg.Split('\n');
            foreach (string str in keyInfo)
            {
                string[] arrTemp = str.Split(':');
                ToolStripMenuItem item = new ToolStripMenuItem();
                item.Name = arrTemp[0];
                item.Text = string.Format("{0}({1})", arrTemp[1], arrTemp[0]);
                item.Click += LblCMSItem_Click;

                lblCms.Items.Add(item);
            }

        }

        private void ShowErrMsg(string msg)
        {
            MessageBox.Show("无法转换对应操作，请查看源码是否有错误！", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
        private void ShowInfoMsg(string msg)
        {
            MessageBox.Show("无法转换对应操作，请查看源码是否有错误！", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void LblCMSItem_Click(object sender, EventArgs e)
        {
            string key = ((ToolStripMenuItem)sender).Name;
            Keys keyObj = Keys.None;
            if (Enum.TryParse<Keys>(key, out keyObj))
            {
                ExecKeyAction(keyObj);
            }
            else
            {
                ShowErrMsg("无法转换对应操作，请查看源码是否有错误！");
            }
        }

        private void lbl_MouseDown(object sender, MouseEventArgs e)
        {
            int xOffset;
            int yOffset;

            if (e.Button == MouseButtons.Left)
            {
                xOffset = -e.X;
                yOffset = -e.Y;
                mouseOffset = new Point(xOffset, yOffset);
                isMouseDown = true;
            }
            else
            {
                //lblCms.Show(lbl.PointToScreen(e.Location));

            }
        }
        private void lbl_MouseMove(object sender, MouseEventArgs e)
        {
            if (isMouseDown)
            {
                Point mousePos = Control.MousePosition;
                mousePos.Offset(mouseOffset.X, mouseOffset.Y);
                Location = mousePos;
            }
        }
        private void lbl_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                isMouseDown = false;
            }
        }

        private void ntf_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (isShow)
            {
                this.Hide();
                isShow = false;
            }
            else
            {
                this.Show();
                isShow = true;
            }
        }

        private void Form1_MouseWheel(object sender, MouseEventArgs e)
        {
            if (e.Delta < 0)
            {
                if (startIndex + step <= len)
                {
                    startIndex = startIndex + step;
                }
            }
            else
            {
                startIndex = startIndex - step;
                if (startIndex < 0)
                {
                    startIndex = 0;
                }
            }
            readStr(strTxt, step);
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            ExecKeyAction(e.KeyCode);
        }

        string preSearchKey = "";
        private void ExecKeyAction(Keys key)
        {
            try
            {
                switch (key)
                {
                    case Keys.V:
                    case Keys.Escape:
                        {
                            SaveReadPoint();
                            this.Hide();
                            isShow = false;
                            break;
                        }
                    case Keys.Q:
                        {
                            SaveReadPoint();
                            ExitForm();
                            break;
                        }
                    case Keys.A:
                        {
                            SaveReadPoint();
                            ReloadStr();
                            break;
                        }
                    case Keys.O:
                        {
                            openStr();
                            break;
                        }
                    case Keys.R:
                        {
                            string sline = Interaction.InputBox("输入行字符数", "字符数", step.ToString(), 100, 100);
                            if (sline != "")
                            {
                                step = int.Parse(sline);
                            }
                            break;
                        }
                    case Keys.H:
                        {
                            ShowInfoMsg(msg);
                            break;
                        }
                    case Keys.C:
                        {
                            if (colorDialog.ShowDialog() == DialogResult.OK)
                            {
                                lbl.ForeColor = colorDialog.Color;
                            }
                            break;
                        }
                    case Keys.B:
                        {
                            if (colorDialog.ShowDialog() == DialogResult.OK)
                            {
                                lbl.BackColor = colorDialog.Color;
                            }
                            break;
                        }
                    case Keys.U:
                        {
                            OpenFileByPath(Encoding.UTF8);
                            break;
                        }
                    case Keys.K:
                        {
                            string size = Interaction.InputBox("输入字体大小", "字体大小", fontsize.ToString(), 100, 100);
                            if (size != "")
                            {
                                fontsize = float.Parse(size);
                            }
                            lbl.Font = new Font("宋体", fontsize);
                            break;
                        }
                    case Keys.L:
                        {
                            string sline = Interaction.InputBox("输入开始数", "输入开始数", startIndex.ToString(), 100, 100);
                            if (sline != "")
                            {

                                startIndex = int.Parse(sline);
                                if (strTxt == "")
                                {
                                    openStr();
                                }
                                readStr(strTxt, step);
                            }
                            break;
                        }
                    case Keys.P:
                        {
                            string percent = ((float)startIndex / (float)strTxt.Length).ToString("0.00%");

                            string sline = Interaction.InputBox("输入阅读进度（百分比）", "输入阅读进度（百分比）", percent, 100, 100);
                            if (sline != "")
                            {
                                if (strTxt == "")
                                {
                                    openStr();
                                }
                                if (sline.EndsWith("%"))
                                {
                                    sline = sline.Replace("%", "");
                                }

                                float tempInt = float.Parse(sline);
                                float strLen = (float)strTxt.Length;

                                startIndex = (int)(strLen * (tempInt / 100));

                                readStr(strTxt, step);
                            }
                            break;
                        }
                    case Keys.F:
                        {
                            string sline = Interaction.InputBox("搜索字符并定位，格式：开始索引-搜索字符；" +
                              "默认开始索引为当前位置，从头开始搜索请设置为0", "搜索", (startIndex + 1) + "-" + preSearchKey, 100, 100);
                            if (!string.IsNullOrEmpty(sline))
                            {
                                string[] tempVal = sline.Split('-');
                                int searchStartIndex = 0;
                                if (tempVal.Length >= 2)
                                {
                                    if (int.TryParse(tempVal[0], out searchStartIndex))
                                    {
                                        tempVal[0] = "";//数组第一个赋值为空，方便下面拼接字符串
                                    }

                                    preSearchKey = string.Join("", tempVal);
                                }
                                else
                                {
                                    preSearchKey = sline;
                                }
                                startIndex = strTxt.IndexOf(preSearchKey, searchStartIndex);
                                readStr(strTxt, step);
                            }
                            break;
                        }
                    case Keys.W:
                    case Keys.Up:
                        {
                            startIndex = startIndex - step;
                            readStr(strTxt, step);
                            break;
                        }
                    case Keys.S:
                    case Keys.Down:
                        {
                            if (startIndex + step <= len)
                            {
                                startIndex = startIndex + step;
                                readStr(strTxt, step);
                            }
                            break;
                        }
                    case Keys.F5: //缩小窗体长度 一次减5
                        {
                            this.Width = this.Width - 5;
                            break;
                        }
                    case Keys.F6:
                        {
                            this.Width = this.Width + 5;
                            break;
                        }
                    case Keys.F7:
                        {
                            this.Height = this.Height - 5;
                            break;
                        }
                    case Keys.F8:
                        {
                            this.Height = this.Height + 5;
                            break;
                        }
                    case Keys.F12:
                        {
                            Clipboard.Clear();
                            Clipboard.SetDataObject(lbl.Text, true);
                            break;
                        }
                    case Keys.F11:
                        {
                            if (strTxt != null && strTxt.Length > 0)
                            {
                                MessageBox.Show(((float)startIndex / (float)strTxt.Length).ToString("0.00%"));
                            }
                            break;
                        }
                }
            }
            catch (Exception ex)
            {
                ShowErrMsg(ex.Message);
            }

        }
        private void ReloadStr()
        {
            OpenFileByPath();
        }

        string filePath = null;
        private void openStr()
        {
            try
            {
                ofd.InitialDirectory = AppDomain.CurrentDomain.BaseDirectory;
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    filePath = ofd.FileName;

                    OpenFileByPath();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void OpenFileByPath(Encoding encoding=null)
        {
            if (!string.IsNullOrEmpty(filePath) && File.Exists(filePath))
            {
                lbl.BorderStyle = BorderStyle.None;

                startIndex = 0;
                int nameStart = filePath.LastIndexOf("\\");
                fileName = filePath.Substring(filePath.LastIndexOf("\\") + 1);
                fileName = fileName.Replace(".txt", "");

                string iniPath = Path.Combine(Application.StartupPath, "readini.txt");
                string tags = "";
                using (StreamReader tagsr = new StreamReader(iniPath, Encoding.UTF8))
                {
                    tags = tagsr.ReadToEnd();
                    tagsr.Close();
                }
                string[] tagArray = tags.Split('|');
                for (int i = 1; i < tagArray.Length; i++)
                {
                    if (tagArray[i].Contains(fileName))
                    {
                        string[] temp = tagArray[i].Split('^');

                        startIndex = int.Parse(temp[1]);
                        break;
                    }
                }

                if (encoding == null)
                {
                    encoding = Encoding.Default;
                }

                using (StreamReader sr = new StreamReader(filePath, encoding))
                {
                    strTxt = sr.ReadToEnd();
                    sr.Close();
                }
                strTxt = strTxt.Replace("\t", " ");
                strTxt = strTxt.Replace("\r", "");
                strTxt = strTxt.Replace("\n", " ");
                len = strTxt.Length;
                readStr(strTxt, step);
            }
        }
        private void readStr(string str, int step)
        {
            if (startIndex < 0)
            {
                startIndex = 0;
            }

            if (len > startIndex)
            {
                if (len > (startIndex + step))
                {
                    lbl.Text = str.Substring(startIndex, step);
                }
                else
                {
                    lbl.Text = str.Substring(startIndex);
                }
            }
        }

        private void ntf_Click(object sender, EventArgs e)
        {
            if (isShow)
            {
                this.Activate();
            }
        }

        private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ExitForm();
        }
        private void ExitForm()
        {
            SaveReadPoint();
            this.Close();
        }

        private void SaveReadPoint()
        {
            string iniPath = Path.Combine(Application.StartupPath, "readini.txt");
            using (FileStream fs = File.Open(iniPath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {

                byte[] tagByte = new byte[fs.Length];
                fs.Read(tagByte, 0, (int)fs.Length);
                string tags = System.Text.Encoding.UTF8.GetString(tagByte);
                if (fileName != "")
                {
                    int index = tags.IndexOf(fileName);
                    if (index < 0)
                    {
                        tags += "|" + fileName + "^" + startIndex;
                    }
                    else
                    {
                        string[] tagArray = tags.Split('|');
                        tags = "";
                        for (int i = 1; i < tagArray.Length; i++)
                        {
                            if (!tagArray[i].Contains(fileName))
                            {
                                tags += "|" + tagArray[i];
                            }
                        }
                        tags += "|" + fileName + "^" + startIndex;
                    }
                }
                fs.SetLength(0);
                byte[] tempByte = System.Text.Encoding.UTF8.GetBytes(tags);
                fs.Write(tempByte, 0, tempByte.Length);
                fs.Flush();
                fs.Close();
            }
        }

        public static string GetAssemblyPath()
        {
            string _CodeBase = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;

            _CodeBase = _CodeBase.Substring(8, _CodeBase.Length - 8);    // 8是 file:// 的长度

            string[] arrSection = _CodeBase.Split(new char[] { '/' });

            string _FolderPath = "";
            for (int i = 0; i < arrSection.Length - 1; i++)
            {
                _FolderPath += arrSection[i] + "/";
            }
            return _FolderPath;
        }
    }
}
